Skip to content

Ghcup distribution - #24

Merged
hsyl20 merged 2 commits into
ghc-9.6-plinthfrom
ghcup-distribution
Jul 31, 2026
Merged

Ghcup distribution#24
hsyl20 merged 2 commits into
ghc-9.6-plinthfrom
ghcup-distribution

Conversation

@hsyl20

@hsyl20 hsyl20 commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@hsyl20
hsyl20 force-pushed the ghcup-distribution branch 2 times, most recently from 9faad0b to ab44982 Compare July 30, 2026 12:35
hsyl20 and others added 2 commits July 30, 2026 22:11
Add automated ghcup distribution for the Plinth standalone compiler.
uplc-ghc is published as a custom third-party ghcup tool named `plinth`,
installable with a stock ghcup >= 0.2.1.0 (the installer DSL for arbitrary
tools) -- no ghcup fork required. It installs side-by-side and never replaces
the user's GHC:

    ghcup config add-release-channel \
      https://input-output-hk.github.io/ghc-plinth/ghcup-plinth.yaml
    ghcup install plinth latest
    ghcup set plinth latest

- generate-ghcup-metadata.py: build the `plinth` channel YAML from the
  per-platform bindist tarballs. A JSON accumulator DB keeps every released
  version installable; the per-platform dlInstallSpec mirrors ghcup's own
  defaultGHCInstallSpec (Unix: configure + make install; Windows: copy).
  Only uplc-ghc is symlinked into ~/.ghcup/bin: the bindist's other tools keep
  their stock names (ghc-pkg, haddock, ...), so linking them would shadow the
  user's GHC, and there is no uplc-prefixed variant of them to link instead.
- plinth-build.sh: fix musl detection for the bindist name. musl's ldd has no
  --version and exits 1 after printing its banner, so `ldd --version | grep
  musl` reported failure under `set -o pipefail` even when it matched, and the
  musl bindist was named as if it were glibc. That name is what the generator
  maps to a ghcup platform, so the musl bindist would have been published as
  Linux_UnknownLinux -- uninstallable on Alpine, since ghcup deliberately does
  not fall back from Alpine to UnknownLinux -- and would have collided with the
  glibc tarball under the same file name in the Release. The suffix renames the
  bindist directory as well as the archive: hadrian names the directory after the
  target platform only, so suffixing just the archive name leaves `tar` with no
  such directory to pack, and the tarball's top-level directory is exactly what
  ghcup is told to descend into (dlSubdir).
- ci.yml: trigger builds on v* tags and add a `release` job that validates a
  real install via stock ghcup (capability-gated), creates the GitHub Release,
  regenerates the gh-pages channel with the real Release URLs, and pushes it.
- plinth-ghcup-test.sh: local stock-ghcup install test.
- README: document installation via ghcup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add plinth-ghcup-test-{linux,linux-musl,macos,windows} jobs that install
each platform's bindist as the custom `plinth` ghcup tool -- the same path
end users take -- on every push, not just on tags. This catches a broken
dlInstallSpec, generator, or metadata-schema drift in the PR that introduces
it rather than only at release time.

- Refactor plinth-ghcup-test.sh to run from just a bindist tarball (no boot
  GHC / source tree): derive the version from the tarball name, locate ghcup's
  dirs via `ghcup whereis`, and translate MSYS<->native paths with cygpath so
  it works on Windows too. The script now capability-gates on ghcup >= 0.2.1.0.
- Keep the ghcup prefix short on Windows. ghcup stages an install in a temp dir
  whose layout repeats the whole install path underneath it, so every character
  of GHCUP_INSTALL_BASE_PREFIX is paid for twice; with the prefix under MSYS's
  /tmp, the staged path of GHC's deepest library files reached 261 characters --
  one over MAX_PATH -- and the copy failed with "The system cannot find the path
  specified". Fall back to $TMPDIR with a warning when the drive root is not
  usable (UNC workspace, read-only root).
- Make ghcup failures legible: ghcup wraps its error codes in an OSC-8 hyperlink
  escape, and GitHub's log viewer swallows it along with the rest of the line,
  hiding every error behind a bare "[". Strip terminal escapes from ghcup's
  output and dump ghcup's own logs before the test env is removed.
- Verify the uplc-* links with -e rather than -L, so a link towards a file the
  bindist does not ship fails the test instead of being shipped broken.
- Assert the musl job really received the musl bindist (EXPECT_MUSL=1), and give
  Alpine the GNU coreutils/findutils/grep that the bindist's `make install`
  (which ghcup runs) is exercised with upstream.
- Gate the `release` job on these install tests (they transitively require the
  builds), and drop its now-redundant inline validation step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@hsyl20
hsyl20 force-pushed the ghcup-distribution branch from ab44982 to f3ba835 Compare July 30, 2026 20:19
@hsyl20
hsyl20 merged commit ea69cbb into ghc-9.6-plinth Jul 31, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant